package com.frame.framework.bean.factory.xml;

import com.frame.framework.bean.factory.BeanDefinition;
import com.frame.framework.bean.factory.MutablePropertyValues;
import com.frame.framework.bean.factory.PropertyValue;
import com.frame.framework.bean.factory.support.BeanDefinitionReader;
import com.frame.framework.bean.factory.support.BeanDefinitionRegistry;
import com.frame.framework.bean.factory.support.SimpleBeanDefinitionRegistry;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import java.io.InputStream;
import java.util.List;

/**
 * @Description 针对 Xml 配置文件进行解析的类
 * @Author Mokairui
 * @Since 2021/11/27
 */
public class XmlBeanDefinitionReader implements BeanDefinitionReader {

    // 申明注册表对象
    private BeanDefinitionRegistry registry;

    public XmlBeanDefinitionReader() {
        registry = new SimpleBeanDefinitionRegistry();
    }

    @Override
    public BeanDefinitionRegistry getRegistry() {
        return registry;
    }

    @Override
    public void loadBeanDefinitions(String configLocation) throws Exception {
        // 使用 Dom4j 进行 xml 配置文件解析
        SAXReader reader = new SAXReader();
        // 获取类路径下的配置文件
        InputStream is = XmlBeanDefinitionReader.class.getClassLoader().getResourceAsStream(configLocation);
        Document document = reader.read(is);
        // 根据 Document 对象获取根标签对象 (beans)
        Element rootElement = document.getRootElement();
        // 获取根标签下所有的 bean 标签对象
        List<Element> beanElements = rootElement.elements("bean");
        // 遍历集合
        beanElements.forEach(beanElement -> {
            // 获取 id 属性
            String id = beanElement.attributeValue("id");
            // 获取 class 属性
            String className = beanElement.attributeValue("class");

            // 将 id 属性和 class 属性封装到 BeanDefinition 对象中
            // 1.创建 BeanDefinition
            BeanDefinition beanDefinition = new BeanDefinition();
            beanDefinition.setId(id);
            beanDefinition.setClassName(className);

            // 创建 MutablePropertyValues 对象
            MutablePropertyValues mutablePropertyValues = new MutablePropertyValues();

            // 获取 bean 标签下所有的 property 标签对象
            List<Element> propertyElements = beanElement.elements("property");
            propertyElements.forEach(propertyElement -> {
                String name = propertyElement.attributeValue("name");
                String ref = propertyElement.attributeValue("ref");
                String value = propertyElement.attributeValue("value");
                PropertyValue propertyValue = new PropertyValue(name, ref, value);
                mutablePropertyValues.add(propertyValue);
            });

            // 将 mutablePropertyValues 对象封装到 BeanDefinition 对象中
            beanDefinition.setPropertyValues(mutablePropertyValues);
        });
    }

}
